package com.itcast.bulls.stock.task.service.impl;

import com.itcast.bulls.stock.common.generator.DateUtils;
import com.itcast.bulls.stock.common.math.MathUtils;
import com.itcast.bulls.stock.common.utils.GlobalConstants;
import com.itcast.bulls.stock.entity.quote.TradeStockQuoteLast;
import com.itcast.bulls.stock.entity.trade.TradePosition;
import com.itcast.bulls.stock.task.dao.trade.ITradePositionDao;
import com.itcast.bulls.stock.task.service.IAccountPositionInterestService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Log4j2
public class AccountPositionInterestServiceImpl implements IAccountPositionInterestService {

    /**
     * 持仓数据层接口
     */
    @Autowired
    private ITradePositionDao tradePositionDao;

    /**
     * 持仓利息利率(四位), 万分比为单位
     */
    private Integer interest = 2;

    /**
     * 缓存服务管理器
     */
    @Autowired
    private RedisCacheManager redisCacheManager;


    /**
     * null 值转换为0
     * @return
     */
    private Long isNullToZero(Long value) {
        return value == null ? 0 : value;
    }

    /**
     * 获取股票产品的最新报价
     *
     * @param stockId
     * @return
     */
    private TradeStockQuoteLast getTradeStockQuoteLast(Long stockId) {

        // 从缓存获取数据
        Cache lastPriceCache = redisCacheManager.getCache(GlobalConstants.STOCK_QUOTE_LAST_PRICE_KEY);
        Cache.ValueWrapper quoteLastWrapper = lastPriceCache.get(stockId);
        TradeStockQuoteLast quoteLast = null;
        if (quoteLastWrapper != null) {
            quoteLast = (TradeStockQuoteLast) quoteLastWrapper.get();
        }

        return quoteLast;
    }

    /**
     * 生成账户的仓位利息信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @XxlJob("accountPositionInterestJob")
    public void generateAccountPositionInterest() {
        String jobParam = XxlJobHelper.getJobParam();
        log.info("Process in generateAccountPositionInterest,param:"+jobParam);

        //获取当天的格式化日期（yyyyMMdd)
        String fmtDay = DateUtils.getFmtToday();
        //1.根据日期，获取所有有效的持仓数据
        //更新当天和之前的仓位数据，不能重复更新计算利息
        List<TradePosition> tradePositions = tradePositionDao.findAllValidPositionsByInterestTime(fmtDay);
        System.out.println(tradePositions==null);
        //2.根据股票id做汇总处理，减少sql查询次数
        Map<Long, List<TradePosition>> groupByStockId = tradePositions.stream().collect(Collectors.groupingBy(TradePosition::getStockId));

        //3.根据股票ID,遍历所有持仓数据
        groupByStockId.forEach((stockId,positions) ->{
            if(null != positions && positions.size()>0){
                //4.获取最新股票行情报价
                TradeStockQuoteLast quoteLast = getTradeStockQuoteLast(stockId);
                if(null != quoteLast){
                    positions.forEach(pos ->{
                        //5.计算仓位市值=持仓数量*股票最新价
                        long totalMarketValue = MathUtils.mul(pos.getVolume(), quoteLast.getLastClosePrice());
                        //6.计算仓位利息，利息=市值*利息率
                        long posInterest = MathUtils.div2Long(MathUtils.mul(totalMarketValue, interest), 10000);
                        //7.累加持仓利息
                        pos.setInterest(isNullToZero(pos.getInterest())+posInterest);
                        //8.要写入利息的更新时间，防止重复计算
                        pos.setInterestTime(fmtDay);
                        //9.更新利息的计算结果以及利息的更新时间
                        tradePositionDao.updateInterest(pos);
                    });
                }

            }

        });
    }
}
